package com.yike.user.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yike.common.exception.BusinessException;
import com.yike.common.tool.LoginUtil;
import com.yike.common.tool.StringUtil;
import com.yike.user.entity.Agent;
import com.yike.user.entity.Shop;
import com.yike.user.entity.User;
import com.yike.user.mapper.AgentMapper;
import com.yike.user.mapper.AgentShopCountMapper;
import com.yike.user.mapper.ShopMapper;
import com.yike.user.mapper.UserMapper;
import com.yike.user.param.*;
import com.yike.user.service.AgentService;
import com.yike.common.base.BaseServiceImpl;
import com.yike.common.pagination.Paging;
import com.yike.common.pagination.PageInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yike.user.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 代理商表 服务实现类
 *
 * @author Sakura
 * @since 2024-08-26
 */
@Slf4j
@Service
public class AgentServiceImpl extends BaseServiceImpl<AgentMapper, Agent> implements AgentService {

    @Autowired
    private AgentMapper agentMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AgentShopCountMapper agentShopCountMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveAgent(AddAgentParam addAgentParam) throws Exception {
        // 此处添加代理商的时候会同步创建一个用户账号
        // 所以需要验证手机号是否存在用户，如果存在则走另外一个接口直接将用户设置为代理商
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getMobile, addAgentParam.getMobile()));
        if (user != null) {
            throw new BusinessException("当前手机号已存在账号，请直接设置为代理商即可");
        }

        // 创建一个用户
        user = new User();
        user.setMobile(addAgentParam.getMobile());
        user.setUserNo(StringUtil.random(32)); // 生成用户ID
        user.setNickname(addAgentParam.getContact());
        user.setCreateBy(LoginUtil.getUserId());
        user.setStatus(1); // 状态为正常
        userMapper.insert(user);

        // 增加一条代理商记录
        Agent agent = new Agent();
        BeanUtils.copyProperties(addAgentParam, agent);
        agent.setAgentNo("66" + StringUtil.getStrNo());
        agent.setUserId(user.getId());
        agent.setCreateBy(LoginUtil.getUserId());

        // 如果上级代理商编号不为空需要验证上级代理商
        if (!StringUtil.isBlank(addAgentParam.getParentAgentNo())) {
            // 获取上级代理商信息
            Agent parentAgent = agentMapper.selectOne(Wrappers.lambdaQuery(Agent.class)
                    .eq(Agent::getAgentNo, addAgentParam.getParentAgentNo()));
            if (parentAgent == null) {
                throw new BusinessException("上级代理商信息异常");
            }
            agent.setParentId(parentAgent.getId());
        }
        agentMapper.insert(agent);

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean setAgent(SetAgentParam setAgentParam) throws Exception {
        // 先获取用户信息
        User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getUserNo, setAgentParam.getUserNo()));
        if (user == null) {
            throw new BusinessException("用户信息异常");
        }

        // 判断当前用户是否是代理商
        Agent agent = agentMapper.selectOne(Wrappers.lambdaQuery(Agent.class)
                .eq(Agent::getUserId, user.getId()));
        if (agent != null) {
            throw new BusinessException("当前用户已经是代理商");
        }

        // 增加一条代理商记录
        agent = new Agent();
        BeanUtils.copyProperties(setAgentParam, agent);
        agent.setAgentNo("66" + StringUtil.getStrNo());
        agent.setUserId(user.getId());
        agent.setCreateBy(LoginUtil.getUserId());

        // 如果上级代理商编号不为空需要验证上级代理商
        if (!StringUtil.isBlank(setAgentParam.getParentAgentNo())) {
            // 获取上级代理商信息
            Agent parentAgent = agentMapper.selectOne(Wrappers.lambdaQuery(Agent.class)
                    .eq(Agent::getAgentNo, setAgentParam.getParentAgentNo()));
            if (parentAgent == null) {
                throw new BusinessException("上级代理商信息异常");
            }
            agent.setParentId(parentAgent.getId());
        }

        agentMapper.insert(agent);

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateAgent(UpdateAgentParam updateAgentParam) throws Exception {
        // 获取代理商信息
        Agent agent = agentMapper.selectOne(Wrappers.lambdaQuery(Agent.class)
                .eq(Agent::getAgentNo, updateAgentParam.getAgentNo()));
        if (agent == null) {
            throw new BusinessException("代理商信息异常");
        }
        BeanUtils.copyProperties(updateAgentParam, agent);

        // 如果上级代理商编号不为空需要验证上级代理商
        if (!StringUtil.isBlank(updateAgentParam.getParentAgentNo())) {
            // 获取上级代理商信息
            Agent parentAgent = agentMapper.selectOne(Wrappers.lambdaQuery(Agent.class)
                    .eq(Agent::getAgentNo, updateAgentParam.getParentAgentNo()));
            if (parentAgent == null) {
                throw new BusinessException("上级代理商信息异常");
            }
            agent.setParentId(parentAgent.getId());
        }

        agentMapper.updateById(agent);

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteAgent(String agentNo) throws Exception {
        // 获取代理商信息
        Agent agent = agentMapper.selectOne(Wrappers.lambdaQuery(Agent.class)
                .eq(Agent::getAgentNo, agentNo));
        if (agent == null) {
            throw new BusinessException("代理商信息异常");
        }
        return super.removeById(agent.getId());
    }

    @Override
    public AgentVo getAgent(String agentNo) throws Exception {
        AgentVo agentVo = agentMapper.getAgentVo(agentNo);
        if (agentVo == null) {
            throw new BusinessException("代理商信息异常");
        }
        // 获取日期
        LocalDate date = LocalDate.now();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将日期格式化为字符串
        String strDate = date.format(formatter);
        // 获取下级代理商分佣数据
        AgentCommissionVo agentCommissionVo = agentShopCountMapper.getAgentCommission(agentVo.getId(),
                strDate, null, null);
        if (agentCommissionVo != null) {
            BeanUtils.copyProperties(agentCommissionVo, agentVo);
        }
        // 获取代理商数量
        Integer agentNumber = agentMapper.getCountSubAgent(agentVo.getId(), strDate);
        agentVo.setAgentNumber(agentNumber);
        // 获取新增代理商数
        Integer addAgentNumber = agentMapper.getAddSubAgent(agentVo.getId(), strDate, null, null);
        agentVo.setAddAgentNumber(addAgentNumber);
        // 获取订单量
        Integer orderNumber = agentShopCountMapper.getAgentOrderNumber(LoginUtil.getAgentId(), strDate, null, null);
        agentVo.setOrderNumber(orderNumber);
        return agentVo;
    }

    @Override
    public Paging<AgentVo> getAgentPageList(AgentPageParam agentPageParam) throws Exception {
        Page<Agent> page = new PageInfo<>(agentPageParam);
        IPage<AgentVo> iPage = agentMapper.getAgentList(page, agentPageParam);
        return new Paging<AgentVo>(iPage);
    }

    @Override
    public Paging<AgentVo> getSubAgentList(SubAgentPageParam subAgentPageParam) throws Exception {
        Page<Agent> page = new PageInfo<>(subAgentPageParam);
        IPage<AgentVo> iPage = agentMapper.getSubAgentList(page, LoginUtil.getUserId(), subAgentPageParam);
        // 获取日期
        LocalDate date = LocalDate.now();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将日期格式化为字符串
        String strDate = date.format(formatter);
        for (AgentVo agentVo : iPage.getRecords()) {
            // 获取下级代理商分佣数据
            AgentCommissionVo agentCommissionVo = agentShopCountMapper.getAgentCommission(agentVo.getId(),
                    strDate, null, null);
            if (agentCommissionVo != null) {
                BeanUtils.copyProperties(agentCommissionVo, agentVo);
            }
            // 获取代理商数量
            Integer agentNumber = agentMapper.getCountSubAgent(agentVo.getId(), strDate);
            agentVo.setAgentNumber(agentNumber);
            // 获取新增代理商数
            Integer addAgentNumber = agentMapper.getAddSubAgent(agentVo.getId(), strDate, null, null);
            agentVo.setAddAgentNumber(addAgentNumber);
            // 获取订单量
            Integer orderNumber = agentShopCountMapper.getAgentOrderNumber(LoginUtil.getAgentId(), strDate, null, null);
            agentVo.setOrderNumber(orderNumber);
        }
        return new Paging<AgentVo>(iPage);
    }

    @Override
    public AgentDataStatisticsVo getAgentDataStatistics(AgentDataStatisticsParam agentDataStatisticsParam) throws Exception {
        // 如果前端传的代理商ID为空则从登录信息获取
        if (agentDataStatisticsParam.getAgentId() == null) {
            agentDataStatisticsParam.setAgentId(LoginUtil.getAgentId());
        }
        // 添加逻辑，如果前端没有传日期参数则表示获取最后一次值守数据
        if (StringUtil.isBlank(agentDataStatisticsParam.getBeginTime()) && StringUtil.isBlank(agentDataStatisticsParam.getEndTime())
                && StringUtil.isBlank(agentDataStatisticsParam.getCertainDate())) {
            // 获取日期
            LocalDate date = LocalDate.now();
            // 定义日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            // 将日期格式化为字符串
            String strDate = date.format(formatter);
            agentDataStatisticsParam.setCertainDate(strDate);
        }
        if (StringUtil.isNotBlank(agentDataStatisticsParam.getBeginTime()) && agentDataStatisticsParam.getBeginTime().length() < 15) {
            agentDataStatisticsParam.setBeginTime(agentDataStatisticsParam.getBeginTime() + " 00:00:00");
        }
        if (StringUtil.isNotBlank(agentDataStatisticsParam.getEndTime()) && agentDataStatisticsParam.getEndTime().length() < 15) {
            agentDataStatisticsParam.setEndTime(agentDataStatisticsParam.getEndTime() + " 23:59:59");
        }
        AgentDataStatisticsVo agentDataStatisticsVo = new AgentDataStatisticsVo();
        // 获取代理商数据
        AgentCommissionVo agentCommissionVo = agentShopCountMapper.getAgentCommission(agentDataStatisticsParam.getAgentId(),
                agentDataStatisticsParam.getCertainDate(), agentDataStatisticsParam.getBeginTime(),
                agentDataStatisticsParam.getEndTime());
        if (agentCommissionVo != null) {
            BeanUtils.copyProperties(agentCommissionVo, agentDataStatisticsVo);
        }

        // 获取代理商数量
        Integer agentNumber = agentMapper.getCountSubAgent(agentDataStatisticsParam.getAgentId(),
                agentDataStatisticsParam.getCertainDate());
        agentDataStatisticsVo.setAgentNumber(agentNumber);
        // 获取新增代理商数
        Integer addAgentNumber = agentMapper.getAddSubAgent(agentDataStatisticsParam.getAgentId(),
                agentDataStatisticsParam.getCertainDate(), agentDataStatisticsParam.getBeginTime(),
                agentDataStatisticsParam.getEndTime());
        agentDataStatisticsVo.setAddAgentNumber(addAgentNumber);
        // 获取店铺数量（含下级代理商店铺）
        Integer shopNumber = agentMapper.getAgentShopNumber(agentDataStatisticsParam.getAgentId(), agentDataStatisticsParam.getCertainDate());
        agentDataStatisticsVo.setShopNumber(shopNumber);
        // 获取值守开启数量
        Integer openGarrisonNumber = agentMapper.getAgentOpenGarrisonNumber(agentDataStatisticsParam.getAgentId(),
                agentDataStatisticsParam.getCertainDate());
        agentDataStatisticsVo.setOpenGarrisonNumber(openGarrisonNumber);
        // 获取值守关闭数量
        Integer closeGarrisonNumber = agentMapper.getAgentCloseGarrisonNumber(agentDataStatisticsParam.getAgentId(),
                agentDataStatisticsParam.getCertainDate());
        agentDataStatisticsVo.setCloseGarrisonNumber(closeGarrisonNumber);
        // 获取值守离线数量
        Integer offlineGarrisonNumber = agentMapper.getAgentOfflineGarrisonNumber(agentDataStatisticsParam.getAgentId(),
                agentDataStatisticsParam.getCertainDate());
        agentDataStatisticsVo.setOfflineGarrisonNumber(offlineGarrisonNumber);
        return agentDataStatisticsVo;
    }

    @Override
    public List<AgentColumnarDataStatisticsVo> getAgentColumnarDataStatistics(AgentColumnarDataStatisticsParam agentColumnarDataStatisticsParam) throws Exception {
        if (agentColumnarDataStatisticsParam.getAgentId() == null) {
            agentColumnarDataStatisticsParam.setAgentId(LoginUtil.getAgentId());
        }

        return agentShopCountMapper.getAgentColumnarDataStatistics(agentColumnarDataStatisticsParam.getAgentId(),
                agentColumnarDataStatisticsParam.getBeginTime(), agentColumnarDataStatisticsParam.getEndTime());
    }

    @Override
    public List<AgentSearchDataVo> getAgentSearchData(AgentSearchDataParam agentSearchDataParam) throws Exception {
        return agentMapper.getAgentSearchData(LoginUtil.getAgentId(), agentSearchDataParam.getKeyword());
    }

    @Override
    public List<AgentSearchListVo> getAgentSearchList(AgentSearchListParam agentSearchListParam) throws Exception {
        // 如果前端传的日期为空则默认查询近七天数据
        if (StringUtil.isBlank(agentSearchListParam.getBeginTime()) && StringUtil.isBlank(agentSearchListParam.getEndTime())) {
            // 定义日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            // 获取当前日期
            LocalDate today = LocalDate.now();
            // 获取七天前的日期
            LocalDate sevenDaysAgo = today.minusDays(6);

            // 将日期格式化为字符串
            String todayStr = today.format(formatter);
            String sevenDaysAgoStr = sevenDaysAgo.format(formatter);
            agentSearchListParam.setBeginTime(sevenDaysAgoStr);
            agentSearchListParam.setEndTime(todayStr);
        }

        List<AgentSearchListVo> agentSearchListVos = new ArrayList<>();
        // 判断是代理商还是商店，需要取不同地方的数据
        if (agentSearchListParam.getType() == 1) {
            // 获取代理商数据
            Agent agent = agentMapper.selectById(agentSearchListParam.getId());
            if (agent == null) {
                throw new BusinessException("代理商信息异常");
            }
            agentSearchListVos = agentShopCountMapper.getAgentSearchList(agentSearchListParam.getId(),
                    agentSearchListParam.getBeginTime(), agentSearchListParam.getEndTime());
            for (AgentSearchListVo agentSearchListVo : agentSearchListVos) {
                agentSearchListVo.setName(agent.getName());
                // 获取代理商数量
                Integer agentNumber = agentMapper.getCountSubAgent(agentSearchListParam.getId(), agentSearchListVo.getCountDate());
                agentSearchListVo.setAgentNumber(agentNumber);
            }
        }
        if (agentSearchListParam.getType() == 2) {
            // 获取店铺信息
            Shop shop = shopMapper.selectById(agentSearchListParam.getId());
            if (shop == null) {
                throw new BusinessException("店铺信息异常");
            }
            agentSearchListVos = agentShopCountMapper.getShopSearchList(agentSearchListParam.getId(),
                    agentSearchListParam.getBeginTime(), agentSearchListParam.getEndTime());
            for (AgentSearchListVo agentSearchListVo : agentSearchListVos) {
                agentSearchListVo.setName(shop.getShopName());
            }
        }
        return agentSearchListVos;
    }

    @Override
    public AgentDateStatisticsVo getAgentDateStatistics(AgentSearchListParam agentSearchListParam) throws Exception {
        if (StringUtil.isNotBlank(agentSearchListParam.getBeginTime()) && agentSearchListParam.getBeginTime().length() < 15) {
            agentSearchListParam.setBeginTime(agentSearchListParam.getBeginTime() + " 00:00:00");
        }
        if (StringUtil.isNotBlank(agentSearchListParam.getEndTime()) && agentSearchListParam.getEndTime().length() < 15) {
            agentSearchListParam.setEndTime(agentSearchListParam.getEndTime() + " 23:59:59");
        }
        AgentDateStatisticsVo agentDateStatisticsVo = new AgentDateStatisticsVo();
        // 判断是代理商还是商店，需要取不同地方的数据
        if (agentSearchListParam.getType() == 1) {
            // 获取代理商数据
            Agent agent = agentMapper.selectById(agentSearchListParam.getId());
            if (agent == null) {
                throw new BusinessException("代理商信息异常");
            }
            agentDateStatisticsVo.setParenAgentId(agent.getParentId());
            // 获取代理商数据
            AgentCommissionVo agentCommissionVo = agentShopCountMapper.getAgentCommission(agentSearchListParam.getId(),
                    null, agentSearchListParam.getBeginTime(),
                    agentSearchListParam.getEndTime());
            if (agentCommissionVo != null) {
                BeanUtils.copyProperties(agentCommissionVo, agentDateStatisticsVo);
            }
            // 获取新增代理商数
            Integer addAgentNumber = agentMapper.getAddSubAgent(agentSearchListParam.getId(),
                    null, agentSearchListParam.getBeginTime(),
                    agentSearchListParam.getEndTime());
            agentDateStatisticsVo.setAddAgentNumber(addAgentNumber);
        }
        if (agentSearchListParam.getType() == 2) {
            // 获取店铺信息
            Shop shop = shopMapper.selectById(agentSearchListParam.getId());
            if (shop == null) {
                throw new BusinessException("店铺信息异常");
            }
            ShopCommissionVo shopCommissionVo = agentShopCountMapper.getShopCommission(agentSearchListParam.getId(), null,
                    agentSearchListParam.getBeginTime(), agentSearchListParam.getEndTime());
            if (shopCommissionVo != null) {
                BeanUtils.copyProperties(shopCommissionVo, agentDateStatisticsVo);
            }
        }
        return agentDateStatisticsVo;
    }

}
